package Railroad.GUI;

import Railroad.Components.OperatorStation;
import Railroad.Components.Signal;
import Railroad.Components.Rail;
import Railroad.Components.SignalDirection;
import Railroad.Components.Switch;
import Railroad.Components.TrackItem;
import Railroad.Zoznam;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.Date;

public class TrackDraw {
    Graphics2D graphics;
    boolean background = false;     // a background is currently drawn
    Zoznam z;
    
    public TrackDraw() {
    }
    
    public void setZoznam(Zoznam z) {
        this.z = z;
    }
    
    public void drawBackground(Graphics g) {
        background = true;
        this.graphics = (Graphics2D)g;
        draw();
    }
    
    public void drawForeground(Graphics g) {
        background = false;
        this.graphics = (Graphics2D)g;
        draw();
    }
    
    private void draw() {
        Color old = graphics.getColor();
        
        for (TrackItem item: z.dajPole()) {
            drawItem(item);
        }
        graphics.setColor(old);
    }
    
    private void drawItem(TrackItem item){
        if (item instanceof Switch) {
           drawSwitch((Switch)item);
        }
        else if (item instanceof Rail) {
            drawRail((Rail)item);
        }
        else if (item instanceof Signal) {
            drawSignal((Signal)item);
        }
        else if (item instanceof OperatorStation) {
            drawOperator((OperatorStation)item);
        }
    }
   
    private void drawSwitch(Switch sw) {
        new SwitchDraw(sw, graphics, background).draw();
    }
    
    private void drawRail(Rail r) {
        if (background)
            return;
        int rasterX = RailroadPanel.rasterX;
        int rasterY = RailroadPanel.rasterY;
        graphics.setColor(r.getColor());
        int startX = r.getStartX();
        int startY = r.getStartY();
        int width = r.getEndX() - r.getStartX();
        int height = r.getEndY() - r.getStartY();
        if (width > 0)
            width++;
        if (width < 0)
            width--;
        if (height > 0)
            height++;
        if (height < 0)
            height--;
        drawLine(startX, startY, width, height);//vykreslenie kolaje
        graphics.drawString(r.getName(), (r.getEndX() + r.getStartX()) / 2 * rasterX, (r.getEndY() + r.getStartY()) / 2 * rasterY + rasterY);
    }
     
    private void drawSignal(Signal s){
        if (background) {
            graphics.setColor(s.getBKColor()); 
            drawRect(s.getStartX(),s.getStartY());//vykreslenie obdlznika na mieste navestidla
            drawRect(s.getStartX()+1,s.getStartY());
            drawRect(s.getStartX()-1,s.getStartY());
        }
        else {
            graphics.setColor(s.getColor());
            int width = RailroadPanel.rasterX;
            int height = RailroadPanel.rasterY;
            
            int points = 3;
            int[] pointsX = new int[points];
            int[] pointsY = new int[points];
            if (s.getDirection() == SignalDirection.Right) {
                pointsX[0] = pointsX[1] = s.getStartX() * width;
                pointsX[2] = (s.getStartX() + 1) * width;
            }
            else {
                pointsX[0] = pointsX[1] = (s.getStartX() + 1) * width;
                pointsX[2] = s.getStartX() * width;
            }
            pointsY[0] = s.getStartY() * height;
            pointsY[1] = (s.getStartY() + 1) * height;
            pointsY[2] = s.getStartY() * height + height / 2;
            
            if (s.isMain())
                graphics.fillPolygon(pointsX, pointsY, points);
            else {
                int strokeWidth = 3;
                int dir = (s.getDirection() == SignalDirection.Right) ? 1 : -1;
                dir *= strokeWidth - 1;
                graphics.setStroke(new BasicStroke(strokeWidth));
                pointsX[0] += dir;
                pointsX[1] += dir;
                pointsY[0] += (strokeWidth + 1) / 2;
                pointsY[1] -= (strokeWidth + 1) / 2;
                graphics.drawLine(pointsX[0], pointsY[0], pointsX[2], pointsY[2]);
                graphics.drawLine(pointsX[1], pointsY[1], pointsX[2], pointsY[2]);
            }
        }
    }
    
    private void drawOperator(OperatorStation station) {
        final Color dayColor = OperatorStation.defaultColor;
        final Color nightColor = Color.BLUE;
        Color drawColor = station.isDay(new Date()) ? dayColor : nightColor;
        graphics.setColor(drawColor);
        
        int rasterX = RailroadPanel.rasterX;
        int rasterY = RailroadPanel.rasterY;
        int posX = station.posX * rasterX;
        int posY = station.posY * rasterY;
        
        int posSmallRectY = station.up ? posY + rasterY - 4 : posY + 3;
        
        graphics.drawRect(posX - rasterX / 2, posY - rasterY / 2, rasterX * 2, rasterY * 2);
        graphics.drawLine(posX + 1, posY + rasterY / 2, posX + rasterX - 1, posY + rasterY / 2);
        graphics.fillRect(posX + rasterX / 2 - 2, posSmallRectY - 2, 4, 4);
    }
     
    private void drawRect(int x,int y) {//vykreslenie obdlznika
        int rasterX = RailroadPanel.rasterX;
        int rasterY = RailroadPanel.rasterY;
        //int width = 1;
        //graphics.drawRect(x, y, 5, 5);
        // graphics.drawRect(x* rasterX - rasterX + width / 2, y * rasterY + rasterY- width / 2, 10, 16);
        //graphics.fillRect(x* rasterX - rasterX + width / 2, y * rasterY + rasterY- width / 2, 10, 15);
        //graphics.fillRect(x* rasterX - rasterX  / 2, y * rasterY + rasterY / 2, 10, 10);
        // x * rasterX - rasterX + width / 2,
        // y1 * rasterY + rasterY / 2,
        graphics.fillRect(x * rasterX, y * rasterY, rasterX, rasterY);
    }
    
    private void drawLine(int x, int y, int width, int height) {
        drawLine(x, y, width, height, true, true);
    }
            
    private void drawLine(int x, int y, int width, int height, boolean extendX, boolean extendY) {
        int strokeWidth = 2;
        graphics.setStroke(new BasicStroke(strokeWidth));
        
        int rasterX = RailroadPanel.rasterX;
        int rasterY = RailroadPanel.rasterY;
        
        int nx1 = x * rasterX + rasterX / 2;
        int nx2 = (x + width) * rasterX + rasterX / 2;
        
        if (extendX) {
            if (nx1 < nx2) {
                nx1 -= rasterX / 2 - strokeWidth / 2;
                nx2 -= rasterX / 2 + (strokeWidth + 1) / 2;
            }
            else if (nx1 > nx2) {
                nx1 += rasterX / 2 - (strokeWidth + 1) / 2;
                nx2 += rasterX / 2 + strokeWidth / 2;
            }
        }

        int ny1 = y * rasterY + rasterY / 2;
        int ny2 = (y + height) * rasterY + rasterY / 2;
        
        if (extendY) {
            if (ny1 < ny2) {
                ny1 -= rasterY / 2 - strokeWidth / 2;
                ny2 -= rasterY / 2 + (strokeWidth + 1) / 2;
            }
            else if (ny1 > ny2) {
                ny1 += rasterY / 2 - (strokeWidth - 1) / 2;
                ny2 += rasterY / 2 + (strokeWidth + 2) / 2;
            }
        }
        
        graphics.drawLine(nx1, ny1, nx2, ny2);
    }
}
